package com.property.manage.service.flowingWater;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.guardchina.framework.util.exception.BusinessException;
import com.property.manage.dao.flowingWater.WalletMapper;
import com.property.manage.enums.WalletType;
import com.property.manage.model.flowingWater.TotalVo;
import com.property.manage.model.flowingWater.WalletEntity;
import com.property.manage.service.resource.BuildingService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;

/**
 * 描述
 *
 * @author lwb
 * @since 2020/7/15
 */
@Component
@Slf4j
public class WalletService {
    @Autowired
    private WalletMapper walletMapper;
    @Autowired
    private BuildingService buildingService;

    //创建默认账户
    public void createWallet(Integer ownerId, Integer villageId) {
        if (findByOwnerId(ownerId) != null) {
            throw new BusinessException("楼栋已经创建钱包", String.format("楼栋id已经创建钱包，[%s]", ownerId));
        }
        WalletEntity entity = new WalletEntity();
        entity.setBuildingId(ownerId);
        entity.setIncome(new BigDecimal(0));
        entity.setExpenditure(new BigDecimal(0));
        entity.setHouse(new BigDecimal(0));
        entity.setParking(new BigDecimal(0));
        entity.setVillageId(villageId);
        entity.setParkingBalance(BigDecimal.ZERO);
        entity.setRentBalance(BigDecimal.ZERO);
        walletMapper.insert(entity);
    }

    //根据用户id查询钱包
    public WalletEntity findByOwnerId(Integer ownerId) {
        QueryWrapper<WalletEntity> qw = new QueryWrapper<>();
        qw.eq("building_id", ownerId);
        return walletMapper.selectOne(qw);
    }

    //删除钱包
    public void delete(Integer id) {
        walletMapper.deleteByOwnerId(id);
    }

    //预存金额
    public BigDecimal deposit(Integer ownerId, BigDecimal money, WalletType walletType) {
        WalletEntity entity = findByOwnerId(ownerId);
        if (entity == null) {
            throw new BusinessException("业主无账户", String.format("楼栋id[%s]", ownerId));
        }
        if (walletType == null || WalletType.PROPERTY.equals(walletType)) {
            //获取账户总余额
            BigDecimal income = entity.getIncome();
            if (income == null) {
                income = new BigDecimal(0);
            }
            //累加总余额
            BigDecimal add = income.add(money);
            //修改总余额
            updateIncome(ownerId, add);
            //获取账户余额，总余额-总支出
            BigDecimal expenditure = entity.getExpenditure();
            if (expenditure == null) {
                expenditure = new BigDecimal(0);
            }
            return add.subtract(expenditure);
            //保存余额流水记录
        } else if (WalletType.RENT.equals(walletType)) {
            BigDecimal rentBalance = entity.getRentBalance();
            rentBalance = rentBalance.add(money);
            updateBalance(ownerId, rentBalance, walletType);
            return rentBalance;

        } else {
            BigDecimal parkingBalance = entity.getParkingBalance();
            parkingBalance = parkingBalance.add(money);
            updateBalance(ownerId, parkingBalance, walletType);
            return parkingBalance;

        }

    }

    //修改账户总余额
    public void updateIncome(Integer ownerId, BigDecimal money) {
        UpdateWrapper<WalletEntity> wrapper = new UpdateWrapper<>();
        wrapper.set("income", money);
        wrapper.eq("building_id", ownerId);
        walletMapper.update(null, wrapper);
    }

    public void updateBalance(Integer ownerId, BigDecimal balance, WalletType walletType) {
        UpdateWrapper<WalletEntity> wrapper = new UpdateWrapper<>();
        wrapper.set(walletType.getDesc(), balance);
        wrapper.eq("building_id", ownerId);
        walletMapper.update(null, wrapper);
    }


    //零钱转存
    public BigDecimal changeDeposit(Integer ownerId, BigDecimal money, WalletType walletType) {
        //查出总支出
        WalletEntity entity = findByOwnerId(ownerId);
        if (entity == null) {
            throw new BusinessException("业主无账户", String.format("业主id[%s]", ownerId));
        }

        if (walletType == null || WalletType.PROPERTY.equals(walletType)) {
            BigDecimal income = entity.getIncome();
            BigDecimal add = income.add(money);
            updateIncome(ownerId, add);
            return add.subtract(entity.getExpenditure());
        } else if (WalletType.RENT.equals(walletType)) {
            BigDecimal rentBalance = entity.getRentBalance();
            rentBalance = rentBalance.add(money);
            updateBalance(ownerId, rentBalance, walletType);
            return rentBalance;
        } else {
            BigDecimal parkingBalance = entity.getParkingBalance();
            parkingBalance = parkingBalance.add(money);
            updateBalance(ownerId, parkingBalance, walletType);
            return parkingBalance;
        }


    }

    public synchronized BigDecimal updateExpenditure(Integer ownerId, BigDecimal money, WalletType walletType) {
        //查出总支出
        WalletEntity entity = findByOwnerId(ownerId);
        if (entity == null) {
            throw new BusinessException("业主无账户", String.format("业主id[%s]", ownerId));
        }
        if (walletType == null || WalletType.PROPERTY.equals(walletType)) {
            //查出余额，比较大小
            BigDecimal decimal = entity.getExpenditure();
            if (decimal == null) {
                decimal = new BigDecimal(0);
            }
            BigDecimal income = entity.getIncome();
            if (income == null) {
                income = new BigDecimal(0);
            }
            BigDecimal subtract = income.subtract(decimal);
            if (subtract.compareTo(money) < 0) {
                throw new BusinessException("账户余额不足", String.format("账户余额[%s]", subtract));
            }
            //累加总支出
            BigDecimal add = decimal.add(money);
            UpdateWrapper<WalletEntity> wrapper = new UpdateWrapper<>();
            wrapper.set("expenditure", add);
            wrapper.eq("building_id", ownerId);
            walletMapper.update(null, wrapper);
            return income.subtract(add);
        } else if (WalletType.RENT.equals(walletType)) {
            BigDecimal rentBalance = entity.getRentBalance();
            if (rentBalance.compareTo(money) < 0) {
                throw new BusinessException("账户余额不足", String.format("账户余额[%s]", rentBalance));
            }
            rentBalance = rentBalance.subtract(money);
            updateBalance(ownerId, rentBalance, walletType);
            return rentBalance;

        } else {
            BigDecimal parkingBalance = entity.getParkingBalance();
            if (parkingBalance.compareTo(money) < 0) {
                throw new BusinessException("账户余额不足", String.format("账户余额[%s]", parkingBalance));
            }
            parkingBalance = parkingBalance.subtract(money);
            updateBalance(ownerId, parkingBalance, walletType);
            return parkingBalance;

        }

    }


    public BigDecimal findBalance(Integer ownerId, WalletType walletType) {
        WalletEntity entity = findByOwnerId(ownerId);
        if (entity == null) {
            throw new BusinessException("业主无账户", String.format("业主id[%s]", ownerId));
        }
        if (walletType == null || WalletType.PROPERTY.equals(walletType)) {
            BigDecimal income = entity.getIncome();
            BigDecimal expenditure = entity.getExpenditure();
            return income.subtract(expenditure);
        } else if (WalletType.RENT.equals(walletType)) {
            return entity.getRentBalance();
        } else {
            return entity.getParkingBalance();
        }

    }

    public BigDecimal find(Integer villageId) {
        TotalVo count = walletMapper.getCount(villageId);
        if (count == null) {
            return new BigDecimal(0);
        }
        return count.getRoutineMoney().subtract(count.getRoutineDeduction());
    }
}
